<template>
  <div class="yd-input">
    <div class="inner-box" @mouseover="iconClean_show=true" @mouseout="iconClean_show=false">
      <input
        class="input"
        :style="clearable?{paddingRight:`${iconWidth+15}px`}:{paddingRight:`${iconWidth+15}px`}"
        v-model="value"
        :type="inputType"
        :placeholder="placeholder"
        :maxlength="maxlength"
      />
      <!-- 图标 -->
      <span ref="iconRef" class="icon-box">
        <!-- text-total -->
        <span v-if="showWordLimit" class="text-total">{{value.length}}/{{maxlength}}</span>
        <!-- clear -->
        <span
          v-if="clearable"
          v-show="iconClean_show&&value"
          class="icon-clean"
          @click.stop="handleClean"
        >x</span>
        <!-- password -->
        <span v-if="type=='password'" class="icon-password" @click.stop="handlePasswordShow">
          <i class="i-round"></i>
        </span>
        <!-- slot -->
        <span style="margin-right:-22px">
          <slot name="rightIcon"></slot>
        </span>
      </span>
    </div>
  </div>
</template>

<script>
import { reactive, toRefs, watch, onMounted, nextTick } from "vue";
export default {
  name: "yd-input",
  props: {
    modelValue: [String, Number],
    type: {
      type: String,
      default: "text"
    },
    showWordLimit: {
      type: Boolean,
      default: false
    },
    maxlength: [String, Number],
    clearable: {
      type: Boolean,
      default: false
    },
    placeholder: {
      type: String,
      default: "请输入"
    }
  },
  setup(props, ctx) {
    const state = reactive({
      value: props.modelValue,
      inputType: props.type,
      iconClean_show: false,
      iconRef: null,
      iconWidth: 0
    });

    const handleClean = () => {
      state.value = "";
    };
    const handlePasswordShow = () => {
      if (state.inputType == "password") {
        state.inputType = "text";
      } else if (state.inputType == "text") {
        state.inputType = "password";
      }
    };
    onMounted(() => {
      nextTick(() => {
        if (state.iconRef) {
          state.iconWidth = state.iconRef.clientWidth;
        }
      });
    });
    watch(
      () => state.value,
      val => {
        ctx.emit("update:modelValue", val);
        ctx.emit("change",val)
      }
    );

    return {
      ...toRefs(state),
      handleClean,
      handlePasswordShow
    };
  }
};
</script>

<style lang="scss" scoped>
.yd-input {
  position: relative;
  width: 240px;
  height: 40px;
  .inner-box {
    position: absolute;
    width: 100%;
    height: 100%;
    z-index: 98;
    .input {
      width: 100%;
      height: 100%;
      padding: 0 15px;
      box-sizing: border-box;
      background-color: #fff;
      border: 1px solid #c0c4cc;
      border-radius: 5px;
      outline: none;
      transition: all 0.2s linear;
      &:focus {
        border-color: #409eff;
      }
    }
    .icon-box {
      position: absolute;
      height: 100%;
      display: flex;
      align-items: center;
      right: 10px;
      top: 0;
      bottom: 0;
      padding-right: 10px;
    }
    .icon-clean {
      width: 12px;
      height: 12px;
      line-height: 9px;
      text-align: center;
      margin-right: 4px;
      font-size: 12px;
      color: #c2cadb;
      border: 1px solid #c2cadb;
      border-radius: 50%;
      cursor: pointer;
    }
    .icon-password {
      width: 16px;
      height: 8px;
      text-align: center;
      margin-right: 8px;
      border-radius: 100%;
      border: 1px solid #c2cadb;
      cursor: pointer;
      .i-round {
        display: block;
        width: 6px;
        height: 6px;
        margin: auto;
        border: 1px solid #c2cadb;
        border-radius: 50%;
      }
    }
    .text-total {
      font-size: 12px;
      color: #999;
      padding-right: 6px;
    }
  }
}
</style>